#ifndef GLOBAL_H
#define GLOBAL_H

#define QT_USE_FAST_CONCATENATION

#include <cmath>
#include <qmath.h>
#include <QDebug>
#include <QVector>
#include <QQuaternion>
#include <QPair>

#include "qlog.h"

//Invalid joint error number
#define INVALID_JOINT -361
//Invalid keyframe error number
#define INVALID_KEYFRAME -361

//Default radius for rendering joints as spheres (see troyglview)
#define JOINT_RADIUS 0.5

//Represents a set of dimensions in 3D space
typedef struct dimension3D{
    float x;
    float y;
    float z;
} Dimension3D;

//Typedef used to simplify the names used with openGL picking
#define MAX_NAMES 5
typedef unsigned int NameGroup[MAX_NAMES];

//Used to identify the type of RobotComponent
enum ComponentType{
    JOINT_GROUP,
    SEGMENT
};

//Typedef for a RGB color
typedef float RGBColor[3];

//Macros for converting to/from degrees and radians
#define DEGREES_TO_RADIANS(a) (((float)a) * (M_PI / 180))
#define RADIANS_TO_DEGREES(a) (((float)a) * (180 / M_PI))

//Macro to convert milliseconds to seconds as a float
#define MSEC_TO_SECF(a) (((float)a) / ((float)1000))
//Macro to convert milliseconds to seconds as a double
#define MSEC_TO_SECD(a) (((double)a) / ((double)1000))
//Macro to convert seconds to milliseconds as an int
#define SEC_TO_MSECI(a) ((int)(a * 1000))

//Returns the number rounded the nearest amount
inline int ROUND_TO(int num, int amount){
    //Use the absolute value to simplify the calculations
    //below
    int rounded = abs(num);
    int remainder = rounded % amount;

    if(remainder >= (amount / 2))
        rounded += (amount - remainder);
    else
        rounded -= remainder;

    //Attach the appropriate sign to the rounded number
    return (num >= 0) ? rounded : -rounded;
}

//Action defaults
#define DEFAULT_NAME "New Action"
#define DEFAULT_DURATION 100

typedef QPair<int, float> JointValue;

typedef QVector<JointValue> JointValues;

typedef struct motionKeyFrame{
    int timestamp;
    JointValues jointValues;
} MotionKeyFrame;

bool operator==(const MotionKeyFrame& frame1, const MotionKeyFrame& frame2);

#ifdef KINECT
#include "Kinect/troystate.h"
MotionKeyFrame troyStateToKeyFrame(kinect::TroyState* troy);
kinect::TroyState* keyFrameToTroyState(MotionKeyFrame frame, QObject* parent = NULL);
#endif

typedef struct soundInfo{
    int timestamp;
    int duration;
    int mediaDuration;
    int trimStart;
    QString* filename;
} SoundInfo;

typedef struct facialInfo{
    int timestamp;
    QString filename;
} FacialExpressionInfo;


#endif // GLOBAL_H
